#include "Sock.hpp"
#include "Protocol.hpp"

void Usage(std::string proc)
{
    std::cout << "Usage: " << proc << " port" << std::endl;
}

void *HandlerRequest(void *arg)
{
    pthread_detach(pthread_self());

    int sockfd = *(int *)arg;
    while (true)
    {
        struct sockaddr_in tmp;
        socklen_t len = sizeof(tmp);
        //接收请求
        char buffer[1024];
        ssize_t size = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&tmp, &len);

        if (size > 0)
        {
            buffer[size] = 0;
            std::string json_string = buffer;
            Request_t req;
            //反序列化请求
            DeserializeRequest(json_string, req);
            int x = req.x;
            int y = req.y;
            char op = req.op;

            Response_t rep;
            switch (op)
            {
            case '+':
                rep.res = x + y;
                break;

            case '-':
                rep.res = x - y;
                break;

            case '*':
                rep.res = x * y;
                break;

            case '/':
                if (y == 0)
                    rep.code = -1;
                else
                    rep.res = x / y;
                break;

            case '%':
                if (y == 0)
                    rep.code = -2;
                else
                    rep.res = x % y;
                break;

            default:
                rep.code = -3;
                break;
            }

            std::string send_string = SerializeResponse(rep);
            send(sockfd, send_string.c_str(), send_string.size(), 0);
            if (rep.code == 0)
                printf("%d %c %d = %d\n", x, op, y, rep.res);
            else
                printf("error\n");

            // std::cout << pthread_self() << ": " << buffer << std::endl;
            // //接收成功
            // size = sendto(sockfd, buffer, size, 0, (struct sockaddr *)&tmp, len);
        }
        else
            break;
    }

    std::cout << "Service done..." << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    //申请套接字
    int listen_sockfd = Sock::Socket();
    Sock::Bind(listen_sockfd, atoi(argv[1]));
    //监听套接字
    Sock::Listen(listen_sockfd);
    while (true)
    {
        //接受连接
        int sockfd = Sock::Accept(listen_sockfd);
        pthread_t tid;
        pthread_create(&tid, nullptr, HandlerRequest, (void *)&sockfd);
    }

    close(listen_sockfd);
    return 0;
}